__proto__: null,
get: function() {
if (!this[kHeadersDistinct]) {
- this[kHeadersDistinct] = {};
+ this[kHeadersDistinct] = { __proto__: null };
const src = this.rawHeaders;
const dst = this[kHeadersDistinct];
__proto__: null,
get: function() {
if (!this[kTrailersDistinct]) {
- this[kTrailersDistinct] = {};
+ this[kTrailersDistinct] = { __proto__: null };
const src = this.rawTrailers;
const dst = this[kTrailersDistinct];
--- /dev/null
+'use strict';
+
+const common = require('../common');
+const assert = require('assert');
+const http = require('http');
+const net = require('net');
+
+// Regression test: sending a __proto__ header must not crash the server
+// when accessing req.headersDistinct or req.trailersDistinct.
+
+const server = http.createServer(common.mustCall((req, res) => {
+ const headers = req.headersDistinct;
+ assert.strictEqual(Object.getPrototypeOf(headers), null);
+ assert.deepStrictEqual(Object.getOwnPropertyDescriptor(headers, '__proto__').value, ['test']);
+ res.end();
+}));
+
+server.listen(0, common.mustCall(() => {
+ const port = server.address().port;
+
+ const client = net.connect(port, common.mustCall(() => {
+ client.write(
+ 'GET / HTTP/1.1\r\n' +
+ 'Host: localhost\r\n' +
+ '__proto__: test\r\n' +
+ 'Connection: close\r\n' +
+ '\r\n',
+ );
+ }));
+
+ client.on('end', common.mustCall(() => {
+ server.close();
+ }));
+
+ client.resume();
+}));
host,
'transfer-encoding': 'chunked'
});
- assert.deepStrictEqual(req.headersDistinct, {
+ assert.deepStrictEqual(req.headersDistinct, Object.assign({ __proto__: null }, {
'connection': ['close'],
'x-req-a': ['eee', 'fff', 'ggg', 'hhh'],
'x-req-b': ['iii; jjj; kkk; lll'],
'host': [host],
- 'transfer-encoding': ['chunked']
- });
+ 'transfer-encoding': ['chunked'],
+ }));
req.on('end', function() {
assert.deepStrictEqual(req.rawTrailers, [
);
assert.deepStrictEqual(
req.trailersDistinct,
- { 'x-req-x': ['xxx', 'yyy'], 'x-req-y': ['zzz; www'] }
+ Object.assign({ __proto__: null }, { 'x-req-x': ['xxx', 'yyy'], 'x-req-y': ['zzz; www'] })
);
res.setHeader('X-Res-a', 'AAA');
'x-res-d': 'JJJ; KKK; LLL',
'transfer-encoding': 'chunked'
});
- assert.deepStrictEqual(res.headersDistinct, {
+ assert.deepStrictEqual(res.headersDistinct, Object.assign({ __proto__: null }, {
'x-res-a': [ 'AAA', 'BBB', 'CCC' ],
'x-res-b': [ 'DDD; EEE; FFF; GGG' ],
'connection': [ 'close' ],
'x-res-c': [ 'HHH', 'III' ],
'x-res-d': [ 'JJJ; KKK; LLL' ],
- 'transfer-encoding': [ 'chunked' ]
- });
+ 'transfer-encoding': [ 'chunked' ],
+ }));
res.on('end', function() {
assert.deepStrictEqual(res.rawTrailers, [
);
assert.deepStrictEqual(
res.trailersDistinct,
- { 'x-res-x': ['XXX', 'YYY'], 'x-res-y': ['ZZZ; WWW'] }
+ Object.assign({ __proto__: null }, { 'x-res-x': ['XXX', 'YYY'], 'x-res-y': ['ZZZ; WWW'] })
);
server.close();
});